#include <bits/stdc++.h>
using namespace std;

/*
1237. 找出给定方程的正整数解
已解答
中等
相关标签
相关企业
提示
给你一个函数  f(x, y) 和一个目标结果 z，函数公式未知，请你计算方程 f(x,y) == z 所有可能的正整数 数对 x 和 y。满足条件的结果数对可以按任意顺序返回。

尽管函数的具体式子未知，但它是单调递增函数，也就是说：

f(x, y) < f(x + 1, y)
f(x, y) < f(x, y + 1)
函数接口定义如下：

interface CustomFunction {
public:
  // Returns some positive integer f(x, y) for two positive integers x and y based on a formula.
  int f(int x, int y);
};
你的解决方案将按如下规则进行评判：

判题程序有一个由 CustomFunction 的 9 种实现组成的列表，以及一种为特定的 z 生成所有有效数对的答案的方法。
判题程序接受两个输入：function_id（决定使用哪种实现测试你的代码）以及目标结果 z 。
判题程序将会调用你实现的 findSolution 并将你的结果与答案进行比较。
如果你的结果与答案相符，那么解决方案将被视作正确答案，即 Accepted 。
 

示例 1：

输入：function_id = 1, z = 5
输出：[[1,4],[2,3],[3,2],[4,1]]
解释：function_id = 1 暗含的函数式子为 f(x, y) = x + y
以下 x 和 y 满足 f(x, y) 等于 5：
x=1, y=4 -> f(1, 4) = 1 + 4 = 5
x=2, y=3 -> f(2, 3) = 2 + 3 = 5
x=3, y=2 -> f(3, 2) = 3 + 2 = 5
x=4, y=1 -> f(4, 1) = 4 + 1 = 5
示例 2：

输入：function_id = 2, z = 5
输出：[[1,5],[5,1]]
解释：function_id = 2 暗含的函数式子为 f(x, y) = x * y
以下 x 和 y 满足 f(x, y) 等于 5：
x=1, y=5 -> f(1, 5) = 1 * 5 = 5
x=5, y=1 -> f(5, 1) = 5 * 1 = 5
 

提示：

1 <= function_id <= 9
1 <= z <= 100
题目保证 f(x, y) == z 的解处于 1 <= x, y <= 1000 的范围内。
在 1 <= x, y <= 1000 的前提下，题目保证 f(x, y) 是一个 32 位有符号整数。
*/

/*
 * // This is the custom function interface.
 * // You should not implement it, or speculate about its implementation
 * class CustomFunction {
 * public:
 *     // Returns f(x, y) for any given positive integers x and y.
 *     // Note that f(x, y) is increasing with respect to both x and y.
 *     // i.e. f(x, y) < f(x + 1, y), f(x, y) < f(x, y + 1)
 *     int f(int x, int y);
 * };
 */

 class CustomFunction {
	public:
	// Returns f(x, y) for any given positive integers x and y.
	// Note that f(x, y) is increasing with respect to both x and y
	// i.e. f(x, y) < f(x + 1, y), f(x, y) < f(x, y + 1)
	int f(int x, int y);
};

// 法一
 class Solution {
	public:
	vector<vector<int>> findSolution(CustomFunction& customfunction, int z) {
		vector<vector<int>> ans;
		int x = 1, y = 1000;
		while (x <= 1000 && y >= 1) {
			int val = customfunction.f(x, y);
			if (val == z) {
				ans.push_back({x, y});
				x++;
				y--;
			} else if (val < z)     x++;
			else    y--;
		}
		return ans;
	}
};

// 法二
class Solution {
	public:
	vector<vector<int>> findSolution(CustomFunction& customfunction, int z) {
		// 推测函数值 因为是递增的 先寻找到大于z的临界值 倒推 满足的存入ans？
		vector<vector<int>> ans;
		int max_num = 1000;
		// 两个变量 无法直接使用二分法对数进行分解 那么怎么处理呢
		// int result = customfunction.f(1,2);
		// cout << result << endl;
		int right = max_num;
		for(int i = 1;i <= max_num;i ++){
			int left = 1;
			if(customfunction.f(i,left) > z || customfunction.f(i,right) < z) continue; // 避免额外计算
			// 二分法找值 由于递增 因此最多一个解 同时右侧的值可以一直使用 因为i增加 y不变的话 值一定在右边
			while(left < right){ 
				int mid = (right - left) / 2 + left;
				int w = customfunction.f(i,mid);
				if(w < z){
					left = mid + 1;
				}
				else if(w == z){
					ans.push_back({i,mid});
					right = mid;
					break;
				}
				else{
					right = mid;
				}
			}
		}
		return ans;
	}
};
